import Obj3D from "../Poly/Obj3D.js";
import Geo from "../Poly/Geo.js";
import Mat from "../Poly/Mat.js";

const defAttr = () => ({
  pointSize: 50,

  //默认配制
  margin: 0.5, //弧线开始的距离[0-0.5]
  arcGap: 0.05, //两条线的差距
  whiteDiff: 0.05, //白色外扩
  lineDia: 0.0, //白色直径
  blueDiff: 0.005, //蓝色外扩
  blueDia: 0.05 - 0.025, //蓝色直径

  // whiteDiff * 2 = blueDia + blueDiff * 2 = 完全覆盖
  // 总直径 = whiteDiff * 2 + lineDia
  // defConfig第二层参数 = 第一层参数 - 总直径 - 一般0.01重叠

  color1: [0.3, 0.53, 1, 0.5],
  color2: [1, 1, 1, 0.5],

  program: "",
  gl: null,
});

//弧线
export default class Arc {
  constructor(attr) {
    Object.assign(this, defAttr(), attr);
  }

  getElement(point) {
    return this._createBroder(point);
  }

  getInsideArcMargin() {
    const { margin, arcGap, whiteDiff, lineDia } = this;
    return margin - arcGap - (whiteDiff * 2 + lineDia) + 0.04;
  }

  _createBroder(point) {
    const { margin, arcGap, gl } = this;
    let Arc = new Obj3D({ depthTest: false });
    //短线
    const configs = this._createArcConfigOfDouble(point, margin);
    Arc.add(gl, this._createArcOfDouble(configs));
    //长线
    const configsL = this._createArcConfigOfDouble(point, margin - arcGap);
    configsL[0].Angle = [configs[0].Angle[1] - 10, configs[0].Angle[0] + 10];
    configsL[1].Angle = [configs[0].Angle[1] - 10, configs[0].Angle[0] + 10];
    Arc.add(gl, this._createArcOfDouble(configsL));

    return Arc;
  }

  //创建弧线配制
  _createArcConfigOfDouble(point, margin) {
    const { whiteDiff, lineDia, blueDiff, blueDia, color1, color2 } = this;

    let angleStart = Math.random() * 360;
    let angleEnd = angleStart + Math.random() * 90 + 45;
    angleEnd = angleEnd > 360 ? angleEnd - 360 : angleEnd;

    const config1 = {
      a_Position: point,
      lineStart: margin,
      lineDia: 0,
      lineDiff: whiteDiff,
      lineColor: color1,
      Angle: [angleStart, angleEnd],
    };

    const config2 = {
      a_Position: point,
      lineStart: margin - whiteDiff - lineDia / 2 + blueDiff + blueDia / 2,
      lineDia: blueDia,
      lineDiff: blueDiff,
      lineColor: color2,
      Angle: [angleStart, angleEnd],
    };
    return [config1, config2];
  }

  _createArcOfDouble(configs) {
    const objW = this._createArc(configs[0]);
    const objB = this._createArc(configs[1]);
    objW.add(this.gl, objB);

    return objW;
  }

  _createArc(config) {
    const { a_Position, lineStart, lineDia, lineDiff, lineColor, Angle } =
      config;
    const { pointSize, program } = this;
    return new Obj3D({
      depthTest: false,
      geo: new Geo({
        data: {
          a_Position: {
            size: 2,
            array: new Float32Array([a_Position.x, a_Position.y]),
          },
        },
      }),
      mat: new Mat({
        program: program,
        mode: ["POINTS"],
        data: {
          u_PointSize: { type: "uniform1f", value: pointSize },
          u_Angle: { type: "uniform2fv", value: Angle },
          u_Set: { type: "uniform1f", value: 0 },
          u_Line: { type: "uniform3fv", value: [lineStart, lineDia, lineDiff] },
          u_line_Color: { type: "uniform4fv", value: lineColor },
        },
      }),
    });
  }
}
